/**
 * Jan 28, 2009
 * @author abhi.sanoujam
 */
package sample;

import java.util.concurrent.CyclicBarrier;

public class OddEvenRunnable implements Runnable {

  private final Counter counter;
  private final int partyId;
  private final CyclicBarrier barrier;

  public OddEvenRunnable(int partyId, Counter counter, CyclicBarrier barrier) {
    this.partyId = partyId;
    this.counter = counter;
    this.barrier = barrier;
  }

  public void run() {
    try {
      System.out.println(Thread.currentThread().getName() + ": Waiting for GREEN signal from main guy...");
      barrier.await();
    } catch (Exception e) {
      e.printStackTrace();
    }
    while (true) {
      synchronized (counter) {
        while (!(counter.isMyTurn(partyId) || counter.isMaxValueReached())) {
          try {
            counter.wait();
          } catch (InterruptedException e) {
            System.out.println(partyId + ": Got Interrupted. Continuing for my turn...");
          }
        }
        if (counter.isMaxValueReached()) {
          // make sure other-threads don't keep waiting for my signal when I'm
          // leaving
          counter.notifyAll();
          break;
        }
        int value = counter.increment();
        System.out.println(Thread.currentThread().getName() + ": Counter Value=" + value);
        try {
          Thread.sleep(500);
        } catch (InterruptedException e) {
          // ignored
        }
        counter.notifyAll();
      }
    }

    System.out.println(Thread.currentThread().getName() + ": DONE!!");
  }

}
